package cc.autoapi.pucong.auto.flow.provider.api.ai;

import cc.autoapi.pucong.auto.flow.provider.api.entity.dto.ApiDesignAiDto;
import cc.autoapi.pucong.auto.flow.provider.api.entity.vo.ApiDesignAiVo;
import cc.autoapi.pucong.auto.flow.provider.api.manager.ApiDesignAiManager;
import com.alibaba.fastjson2.JSON;
import cc.autoapi.pucong.auto.flow.core.root.utils.ApplicationContextUtil;
import cc.autoapi.pucong.auto.flow.core.root.utils.ThreadPoolUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

@Slf4j
@ServerEndpoint(value = "/api/ai/flow/{chatId}")
@Component
public class WebSocketApiEdit {

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(@PathParam("chatId") String chatId, Session session) {
        log.info("有新连接加入：{}，chatId：{}", session.getId(), chatId);
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("chatId") String chatId, Session session) {
        ApiDesignAiManager apiDesignAiManager = (ApiDesignAiManager) ApplicationContextUtil.getBean(ApiDesignAiManager.class);
        apiDesignAiManager.removeChat(chatId);
        log.info("关闭连接：" + chatId);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param chatId
     * @param message
     * @param session
     */
    @OnMessage
    public void onMessage(@PathParam("chatId") String chatId, String message, Session session) {
        ThreadPoolUtils.executor(() -> {
            ApiDesignAiDto apiDesignAiDto = JSON.parseObject(message, ApiDesignAiDto.class);
            ApiDesignAiManager apiDesignAiManager = (ApiDesignAiManager) ApplicationContextUtil.getBean(ApiDesignAiManager.class);
            ApiDesignAiVo vo = apiDesignAiManager.aiDesign(chatId, apiDesignAiDto);
            ObjectMapper objectMapper = new ObjectMapper();
            String resStr = "";
            try {
                resStr = objectMapper.writeValueAsString(vo);
            } catch (JsonProcessingException e) {
                log.error("序列化api信息失败", e);
                resStr = "获取日志信息失败，序列化api信息失败";
            }
            sendMessage(session, resStr, 0);
        });
    }

    @OnError
    public void onError(@PathParam("chatId") String chatId, Session session, Throwable error) {
        ApiDesignAiManager apiDesignAiManager = (ApiDesignAiManager) ApplicationContextUtil.getBean(ApiDesignAiManager.class);
        apiDesignAiManager.removeChat(chatId);
        log.info("有一连接关闭：{}，chatId：{}", session.getId(), chatId);
        log.error("发生错误", error);
        error.printStackTrace();
    }

    public void sendMessage(Session session, String message, int count) {
        if (count > 5) {
            return;
        }
        synchronized (this) {
            try {
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                log.error("发送消息失败，5次失败后停止发送，失败次数：" + count, e);
                this.sendMessage(session, message, ++count);
            }
        }
    }
}
